package com.example.testapp.config.image

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Environment
import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.security.MessageDigest
import kotlin.math.max
import kotlin.math.round
import kotlin.random.Random

/**
 * 账单图片管理器，负责图片的存储和管理
 * 使用哈希分散存储方案
 */
class BalanceImageManager private constructor(context: Context) {
    private val TAG = "BalanceImageManager"
    
    companion object {
        private const val ROOT_DIR = "app_balance"
        private const val IMAGES_DIR = "images"
        private const val THUMBNAILS_DIR = "thumbnails"
        private const val TEMP_DIR = "temp"
        
        private var instance: BalanceImageManager? = null
        
        /**
         * 获取BalanceImageManager的单例实例
         */
        @JvmStatic
        fun getInstance(context: Context): BalanceImageManager {
            return instance ?: synchronized(this) {
                instance ?: BalanceImageManager(context).also { instance = it }
            }
        }
    }
    
    private val context: Context = context.applicationContext
    
    init {
        initDirectories()
    }
    
    /**
     * 初始化目录结构
     */
    private fun initDirectories() {
        val rootDir = File(context.getExternalFilesDir(null), ROOT_DIR)
        val imagesDir = File(rootDir, IMAGES_DIR)
        val thumbnailsDir = File(rootDir, THUMBNAILS_DIR)
        val tempDir = File(rootDir, TEMP_DIR)
        
        createDirectoryIfNotExists(rootDir)
        createDirectoryIfNotExists(imagesDir)
        createDirectoryIfNotExists(thumbnailsDir)
        createDirectoryIfNotExists(tempDir)
    }
    
    /**
     * 如果目录不存在，则创建
     */
    private fun createDirectoryIfNotExists(directory: File): Boolean {
        if (!directory.exists()) {
            val created = directory.mkdirs()
            if (!created) {
                Log.e(TAG, "创建目录失败: ${directory.absolutePath}")
                return false
            }
        }
        return true
    }
    
    /**
     * 保存临时图片
     * @param bitmap 要保存的位图
     * @return 临时文件路径，失败返回null
     */
    fun saveTempImage(bitmap: Bitmap): String? {
        val tempDir = File(context.getExternalFilesDir(null), "$ROOT_DIR/$TEMP_DIR")
        val fileName = "tmp_${System.currentTimeMillis()}_${Random.nextInt(10000)}.jpg"
        val outputFile = File(tempDir, fileName)
        
        return try {
            FileOutputStream(outputFile).use { out ->
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
            }
            outputFile.absolutePath
        } catch (e: Exception) {
            Log.e(TAG, "保存临时图片失败", e)
            null
        }
    }
    
    /**
     * 将临时图片移动到永久存储
     * @param tempPath 临时图片路径
     * @param balanceId 账单ID
     * @param order 图片序号
     * @return 永久存储路径，失败返回null
     */
    fun moveToPermStorage(tempPath: String, balanceId: Long, order: Int): String? {
        val tempFile = File(tempPath)
        if (!tempFile.exists()) {
            Log.e(TAG, "临时文件不存在: $tempPath")
            return null
        }
        
        try {
            // 计算文件的MD5哈希值前4位作为子目录
            val fileHash = calculateMD5(tempFile) ?: return null
            
            val dirHash = fileHash.substring(0, 2)
            val fileName = "balance_${balanceId}_${System.currentTimeMillis()}_$order.jpg"
            
            // 创建子目录
            val imagesDir = File(context.getExternalFilesDir(null), "$ROOT_DIR/$IMAGES_DIR/$dirHash")
            createDirectoryIfNotExists(imagesDir)
            
            // 创建目标文件
            val destFile = File(imagesDir, fileName)
            
            // 复制文件
            if (copyFile(tempFile, destFile)) {
                // 删除临时文件
                if (!tempFile.delete()) {
                    Log.w(TAG, "删除临时文件失败: $tempPath")
                }
                
                // 生成缩略图
                createThumbnail(destFile.absolutePath)
                
                return destFile.absolutePath
            } else {
                return null
            }
        } catch (e: Exception) {
            Log.e(TAG, "移动文件到永久存储失败", e)
            return null
        }
    }
    
    /**
     * 创建图片的缩略图
     * @param imagePath 原图路径
     * @return 缩略图路径，失败返回null
     */
    fun createThumbnail(imagePath: String): String? {
        val imageFile = File(imagePath)
        if (!imageFile.exists()) {
            Log.e(TAG, "原图文件不存在: $imagePath")
            return null
        }
        
        try {
            // 获取文件名和目录哈希
            val fileName = imageFile.name
            val parentName = imageFile.parentFile?.name ?: return null
            val thumbnailName = fileName.replace(".jpg", "_thumb.jpg")
            
            // 创建缩略图目录
            val thumbnailDir = File(context.getExternalFilesDir(null), "$ROOT_DIR/$THUMBNAILS_DIR/$parentName")
            createDirectoryIfNotExists(thumbnailDir)
            
            // 创建缩略图文件
            val thumbnailFile = File(thumbnailDir, thumbnailName)
            
            // 生成缩略图
            val originalBitmap = BitmapFactory.decodeFile(imagePath) ?: run {
                Log.e(TAG, "解码图片失败: $imagePath")
                return null
            }
            
            // 计算缩略图尺寸（最大宽度或高度为200像素）
            val width = originalBitmap.width
            val height = originalBitmap.height
            val scale = 200.0f / max(width, height)
            val thumbWidth = round(width * scale).toInt()
            val thumbHeight = round(height * scale).toInt()
            
            val thumbnailBitmap = Bitmap.createScaledBitmap(originalBitmap, thumbWidth, thumbHeight, true)
            originalBitmap.recycle()
            
            // 保存缩略图
            FileOutputStream(thumbnailFile).use { out ->
                thumbnailBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out)
                thumbnailBitmap.recycle()
            }
            
            return thumbnailFile.absolutePath
        } catch (e: Exception) {
            Log.e(TAG, "创建缩略图失败", e)
            return null
        }
    }
    
    /**
     * 删除图片（同时删除原图和缩略图）
     * @param imagePath 图片路径
     * @return 是否删除成功
     */
    fun deleteImage(imagePath: String): Boolean {
        val imageFile = File(imagePath)
        if (!imageFile.exists()) {
            return true // 文件不存在，视为删除成功
        }
        
        // 删除原图
        val deleted = imageFile.delete()
        
        // 尝试删除对应的缩略图
        try {
            val fileName = imageFile.name
            val parentName = imageFile.parentFile?.name ?: return deleted
            val thumbnailName = fileName.replace(".jpg", "_thumb.jpg")
            
            val thumbnailFile = File(
                context.getExternalFilesDir(null),
                "$ROOT_DIR/$THUMBNAILS_DIR/$parentName/$thumbnailName"
            )
            
            if (thumbnailFile.exists() && !thumbnailFile.delete()) {
                Log.w(TAG, "删除缩略图失败: ${thumbnailFile.absolutePath}")
            }
        } catch (e: Exception) {
            Log.e(TAG, "删除缩略图时出错", e)
        }
        
        return deleted
    }
    
    /**
     * 清理临时目录中的文件
     * @param maxAgeMillis 文件最大保留时间（毫秒）
     * @return 清理的文件数量
     */
    fun cleanupTempFiles(maxAgeMillis: Long): Int {
        val tempDir = File(context.getExternalFilesDir(null), "$ROOT_DIR/$TEMP_DIR")
        if (!tempDir.exists()) return 0
        
        val files = tempDir.listFiles() ?: return 0
        
        var count = 0
        val currentTime = System.currentTimeMillis()
        
        for (file in files) {
            if (file.isFile && (currentTime - file.lastModified() > maxAgeMillis)) {
                if (file.delete()) {
                    count++
                } else {
                    Log.w(TAG, "删除临时文件失败: ${file.absolutePath}")
                }
            }
        }
        
        return count
    }
    
    /**
     * 计算文件的MD5哈希值
     */
    private fun calculateMD5(file: File): String? {
        return try {
            FileInputStream(file).use { fis ->
                val md = MessageDigest.getInstance("MD5")
                val buffer = ByteArray(8192)
                var read: Int
                
                while (fis.read(buffer).also { read = it } != -1) {
                    md.update(buffer, 0, read)
                }
                
                val digest = md.digest()
                digest.joinToString("") { "%02x".format(it) }
            }
        } catch (e: Exception) {
            Log.e(TAG, "计算MD5失败", e)
            null
        }
    }
    
    /**
     * 复制文件
     */
    private fun copyFile(sourceFile: File, destFile: File): Boolean {
        return try {
            FileInputStream(sourceFile).use { input ->
                FileOutputStream(destFile).use { output ->
                    val buffer = ByteArray(8192)
                    var read: Int
                    while (input.read(buffer).also { read = it } != -1) {
                        output.write(buffer, 0, read)
                    }
                }
            }
            true
        } catch (e: Exception) {
            Log.e(TAG, "复制文件失败", e)
            false
        }
    }
    
    /**
     * 获取外部存储状态
     * @return 是否可用
     */
    fun isExternalStorageWritable(): Boolean {
        val state = Environment.getExternalStorageState()
        return Environment.MEDIA_MOUNTED == state
    }
} 